package main

import (
	"fmt"
	"github.com/orcaman/concurrent-map"
	"sync"
)

type RWMap struct { // 一个读写锁保护的线程安全的map
	sync.RWMutex // 读写锁保护下面的map字段
	m map[int]int
}
// 新建一个RWMap
func NewRWMap(n int) *RWMap {
	return &RWMap{
		m: make(map[int]int, n),
	}
}
func (m *RWMap) Get(k int) (int, bool) { //从map中读取一个值
	m.RLock()
	defer m.RUnlock()
	v, existed := m.m[k] // 在锁的保护下从map中读取
	return v, existed
}
func (m *RWMap) Set(k int, v int) { // 设置一个键值对
	m.Lock()              // 锁保护
	defer m.Unlock()
	m.m[k] = v
}
func (m *RWMap) Delete(k int) { //删除一个键
	m.Lock()                   // 锁保护
	defer m.Unlock()
	delete(m.m, k)
}
func (m *RWMap) Len() int { // map的长度
	m.RLock()   // 锁保护
	defer m.RUnlock()
	return len(m.m)
}
func (m *RWMap) Each(f func(k, v int) bool) { // 遍历map
	m.RLock()             //遍历期间一直持有读锁
	defer m.RUnlock()
	for k, v := range m.m {
		if !f(k, v) {
			return
		}
	}
}

type mapKey struct {
	key int
}

func main() {
	// key modify
	//var m = make(map[mapKey]string)
	//var key = mapKey{10}
	//m[key] = "hello"
	//fmt.Printf("m[key]=%s\n", m[key])
	//// 修改key的字段的值后再次查询map，无法获取刚才add进去的值
	//key.key = 100
	//fmt.Printf("再次查询m[key]=%s\n", m[key])

	// not init map
	//var m1 map[int]int
	//v, ok := m1[100]
	//fmt.Println(v, ok)

	// read and write concurrent
	//var m = make(map[int]int,10) // 初始化一个map
	//go func() {
	//	for {
	//		m[1] = 1 //设置key
	//	}
	//}()
	//go func() {
	//	for {
	//		_ = m[2] //访问这个map
	//	}
	//}()
	//select {}

	// read and write concurrent
	//var m = NewRWMap(10) // 初始化一个map
	//go func() {
	//	for {
	//		m.Set(1, 1)	//设置key
	//	}
	//}()
	//go func() {
	//	for {
	//		_, _ = m.Get(2) //访问这个map
	//	}
	//}()
	//select {}

	// Create a new map.
	m := cmap.New()
	// Sets item within map, sets "bar" under key "foo"
	m.Set("foo", "bar")
	// Retrieve item from map.
	if tmp, ok := m.Get("foo"); ok {
		bar := tmp.(string)
		fmt.Printf("bar is %v", bar)
	}
	// Removes item under key "foo"
	m.Remove("foo")
}
